﻿namespace TfsCloudDeploy.Workflow.Core.Editors
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Drawing.Design;
    using System.ComponentModel;
    using System.Windows.Forms.Design;
    using System.Windows.Forms;
    using Microsoft.TeamFoundation.Build.Client;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using System.Activities;
    using System.Collections;
    using Microsoft.TeamFoundation.Build.Workflow;

    /// <summary>
    /// The custom UI editor for the TargetBuildLabel type.
    /// </summary>
    public class TargetBuildLabelEditor : UITypeEditor
    {
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (provider != null)
            {
                IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

                if (editorService != null)
                {
                    IBuildDefinition buildDefinition = (IBuildDefinition)provider.GetService(typeof(IBuildDefinition));

                    // Definition process parameters. Note that parameters not overriden are not available in this collection. You will need to
                    // get their value from the template parameters that holds the default values.
                    IDictionary<String, Object> processParameters = WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters);

                    // Template (default) process parameters.
                    List<DynamicActivityProperty> templateProcessParameters = WorkflowUtility.GetPropertyMetadata(buildDefinition);

                    TargetBuildLabel targetBuildLabel = value as TargetBuildLabel;

                    using (BuildLabelsDialog buildLabelsDialog = new BuildLabelsDialog())
                    {
                        try
                        {
                            if (processParameters.ContainsKey("AvailableBuildsPattern"))
                                buildLabelsDialog.AvailableBuildsPattern = (string)processParameters["AvailableBuildsPattern"];
                            else
                                buildLabelsDialog.AvailableBuildsPattern = WorkflowUtility.GetStringValue(templateProcessParameters.Single((pm) => { return pm.Name.Equals("AvailableBuildsPattern"); }).Value);

                            if (processParameters.ContainsKey("BuildLabelOwnerName"))
                                buildLabelsDialog.BuildLabelOwnerName = (string)processParameters["BuildLabelOwnerName"];
                            else
                                buildLabelsDialog.BuildLabelOwnerName = WorkflowUtility.GetStringValue(templateProcessParameters.Single((pm) => { return pm.Name.Equals("BuildLabelOwnerName"); }).Value);

                            if (processParameters.ContainsKey("BuildLabelSourceControlScope"))
                                buildLabelsDialog.BuildLabelSourceControlScope = (string)processParameters["BuildLabelSourceControlScope"];
                            else
                                buildLabelsDialog.BuildLabelSourceControlScope = WorkflowUtility.GetStringValue(templateProcessParameters.Single((pm) => { return pm.Name.Equals("BuildLabelSourceControlScope"); }).Value);

                            if (processParameters.ContainsKey("ForceUseABuildLabel"))
                                buildLabelsDialog.ForceUseABuildLabel = Convert.ToBoolean(processParameters["ForceUseABuildLabel"]);
                            else
                                buildLabelsDialog.ForceUseABuildLabel = WorkflowUtility.GetBoolValue(templateProcessParameters.Single((pm) => { return pm.Name.Equals("ForceUseABuildLabel"); }).Value);

                            if (processParameters.ContainsKey("MaxNumberOfBuildLabelsToShow"))
                                buildLabelsDialog.MaxNumberOfBuildLabelsToShow = Convert.ToInt32(processParameters["MaxNumberOfBuildLabelsToShow"]);
                            else
                                buildLabelsDialog.MaxNumberOfBuildLabelsToShow = WorkflowUtility.GetInt32Value(templateProcessParameters.Single((pm) => { return pm.Name.Equals("MaxNumberOfBuildLabelsToShow"); }).Value);

                            if (processParameters.ContainsKey("ExcludeLabelsForFailedBuilds"))
                                buildLabelsDialog.ExcludeLabelsForFailedBuilds = Convert.ToBoolean(processParameters["ExcludeLabelsForFailedBuilds"]);
                            else
                                buildLabelsDialog.ExcludeLabelsForFailedBuilds = WorkflowUtility.GetBoolValue(templateProcessParameters.Single((pm) => { return pm.Name.Equals("ExcludeLabelsForFailedBuilds"); }).Value);

                            if (processParameters.ContainsKey("OnlyIncludeBuildsWithListedBuildQualities"))
                                buildLabelsDialog.AcceptableBuildQualities = (string[])processParameters["OnlyIncludeBuildsWithListedBuildQualities"];
                            else
                                buildLabelsDialog.AcceptableBuildQualities = WorkflowUtility.GetStringArrayValue(templateProcessParameters.Single((pm) => { return pm.Name.Equals("OnlyIncludeBuildsWithListedBuildQualities"); }).Value);

                            buildLabelsDialog.TeamProjectName = buildDefinition.TeamProject;
                            buildLabelsDialog.VersionControlServer = (VersionControlServer)buildDefinition.BuildServer.TeamProjectCollection.GetService(typeof(VersionControlServer));

                            if (editorService.ShowDialog(buildLabelsDialog) == DialogResult.OK)
                            {
                                TargetBuildLabel newTargetBuildLabel = new TargetBuildLabel();
                                newTargetBuildLabel.LabelName = buildLabelsDialog.TargetBuildLabel;

                                return newTargetBuildLabel;
                            }

                            return value;
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(string.Format("[TargetBuildLabelEditor] ERROR: {0}.\r\nStackTrace: {1}", ex.Message, ex.StackTrace));
                        }
                    }
                }
                else
                {
                    MessageBox.Show("[TargetBuildLabelEditor] EditorService object is null. Returning default value.");
                }

            }
            else
            {
                MessageBox.Show("[TargetBuildLabelEditor] Provider object is null. Returning default value.");
            }

            return value;
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
    }
}
